package com.example.robertluozizhao.framecollectdemo.activity;

import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.os.Build;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;

import com.example.robertluozizhao.framecollectdemo.R;

import java.io.IOException;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

/**
 * @author luo_zi_zhao
 * @version V1.0 相机api 使用
 * @FileName com.example.robertluozizhao.framecollectdemo.activity
 * @date 2020/3/13 17:06
 */

public class CameraApi1Activity extends Activity {


    private static final String[] REQUIRED_PERMISSIONS = {Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE};
    private static final int REQUEST_PERMISSIONS_CODE = 1;
    @BindView(R.id.sv_camera1)
    SurfaceView mSvCamera1;

    private String TAG = this.getClass().getSimpleName();

    @Nullable
    private Camera.CameraInfo mFrontCameraInfo = null;
    private int mFrontCameraId = -1;
    @Nullable
    private Camera.CameraInfo mBackCameraInfo = null;
    private int mBackCameraId = -1;
    private Camera mCamera;
    private boolean mFrontCameraTag = true;
    private boolean mBackCameraTag = false;
    private int mNumberOfCameras;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera1);
        ButterKnife.bind(this);

        /**
         * 1.权限校验 （6.0）
         * 2.检测摄像头信息
         * 3.打开摄像头
         * 4.配置预览数据
         * 5.设置surface
         * 6.开启预览
         * 7.结束预览
         * 8.停止摄像头
         */

        // 动态权限检查
        if (!isRequiredPermissionsGranted() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            requestPermissions(REQUIRED_PERMISSIONS, REQUEST_PERMISSIONS_CODE);
        }
        initCameraInfo();

    }

    private void intiCameraPreviewParams() {
        if (mCamera != null) {
            setPreviewSize(3,4);
            setPreviewSurface(mSvCamera1.getHolder());
            startPrev();
        }
//        mCamera.setDisplayOrientation(); // 屏幕校验矫正方法
    }

    @Override
    protected void onResume() {
        super.onResume();

    }


    private void startCamera() {
        if (mCamera != null) {
            throw new RuntimeException("相机已经被开启，无法同时开启多个相机实例！");
        }

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
            if (mFrontCameraTag) {
                // 优先开启前置摄像头
                mCamera = Camera.open(mFrontCameraId);
                mFrontCameraTag = false;
                mBackCameraTag = true;
            } else if (mBackCameraTag) {
                // 没有前置，就尝试开启后置摄像头
                mCamera = Camera.open(mBackCameraId);
                mBackCameraTag = false;
                mFrontCameraTag = true;
            } else {
                throw new RuntimeException("没有任何相机可以开启！");
            }

            //设置 校验修正方向
            if (!mFrontCameraTag) {
                mCamera.setDisplayOrientation(getCameraDisplayOrientation(mFrontCameraInfo));
            }
            if (!mBackCameraTag) {
                mCamera.setDisplayOrientation(getCameraDisplayOrientation(mBackCameraInfo));
            }
        }
    }


    /**
     * 初始化摄像头信息。
     */
    private void initCameraInfo() {
        // 获取摄像头个数
        mNumberOfCameras = Camera.getNumberOfCameras();
        for (int cameraId = 0; cameraId < mNumberOfCameras; cameraId++) {
            Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
            Camera.getCameraInfo(cameraId, cameraInfo);
            if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
                // 后置摄像头信息
                mBackCameraId = cameraId;
                mBackCameraInfo = cameraInfo;
            } else if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                // 前置摄像头信息
                mFrontCameraId = cameraId;
                mFrontCameraInfo = cameraInfo;
            }
        }

    }


    /**
     * 判断我们需要的权限是否被授予，只要有一个没有授权，我们都会返回 false。
     *
     * @return true 权限都被授权
     */
    private boolean isRequiredPermissionsGranted() {
        for (String permission : REQUIRED_PERMISSIONS) {
            if (ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_DENIED) {
                return false;
            }
        }
        return true;
    }

    @OnClick({R.id.btn_start_camera, R.id.btn_start_preview, R.id.btn_stop_preview, R.id.btn_stop_camera})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.btn_start_camera:
                startCamera();
                break;
            case R.id.btn_start_preview:
                startPreview();
                break;
            case R.id.btn_stop_preview:
                stopPrev();
                break;
            case R.id.btn_stop_camera:
                stopCamera();
                break;
        }
    }

    private void startPreview() {
        intiCameraPreviewParams();
    }

    private void stopCamera() {
        if (mCamera != null) {
            mCamera.release();
            mCamera = null;
        }
    }

    /**
     * 根据比例设置预览 尺寸
     * @param shortSide
     * @param longSide
     */
    private void setPreviewSize(int shortSide, int longSide) {
        if (mCamera != null && shortSide != 0 && longSide != 0) {
            float aspectRatio = (float) longSide / shortSide;
            Camera.Parameters parameters = mCamera.getParameters();
            List<Camera.Size> supportedPreviewSizes = parameters.getSupportedPreviewSizes();
            for (Camera.Size previewSize : supportedPreviewSizes) {

                Log.d(TAG, "setPreviewSize: width" + previewSize.width + ",height:" + previewSize.height);

                if ((float) previewSize.width / previewSize.height == aspectRatio && previewSize.height <= shortSide && previewSize.width <= longSide) {
                    parameters.setPreviewSize(previewSize.width, previewSize.height);
                    mCamera.setParameters(parameters);
                    break;
                }
            }
        }
    }

    /**
     * 设置预览 surface
     * @param previewSurface
     */
    private void setPreviewSurface(SurfaceHolder previewSurface) {
        if (mCamera != null && previewSurface != null) {
            try {
                mCamera.setPreviewDisplay(previewSurface);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 开始预览。
     */
    private void startPrev() {
        if (mCamera != null) {
            mCamera.startPreview();
            Log.d(TAG, "startPreview() called");
        }
    }

    /**
     * 停止预览。
     */
    private void stopPrev() {
        if (mCamera != null) {
            mCamera.stopPreview();
            Log.d(TAG, "stopPreview() called");
        }
    }

    /**
     * 获取校验修正角度
     *
     * @param cameraInfo
     * @return
     */
    private int getCameraDisplayOrientation(Camera.CameraInfo cameraInfo) {
        int rotation = getWindowManager().getDefaultDisplay().getRotation();
        int degrees = 0;//摄像头传感器方向
        switch (rotation) {
            case Surface.ROTATION_0:
                degrees = 0;
                break;
            case Surface.ROTATION_90:
                degrees = 90;
                break;
            case Surface.ROTATION_180:
                degrees = 180;
                break;
            case Surface.ROTATION_270:
                degrees = 270;
                break;
        }
        int result;
        if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            //cameraInfo.orientation 屏幕方向
            result = (cameraInfo.orientation + degrees) % 360;
            result = (360 - result) % 360;  // compensate the mirror
        } else {  // back-facing
            result = (cameraInfo.orientation - degrees + 360) % 360;
        }
        Log.d(TAG, "getCameraDisplayOrientation() 摄像头传感器方向degrees："+degrees+",屏幕方向cameraInfo.orientation:"+
        cameraInfo.orientation+",整修角度result:"+result);
        return result;
    }
}
